#ifndef UTIL_H
#define UTIL_H

#include <iostream>
#include <sstream>
#include <QScreen>
#include <QWidget>
#include <QLabel>
#include <QString>
#include <QFrame>
#include <QTimer>
#include <QSettings>
#include <QMenuBar>
#include <QToolBar>
#include <QVBoxLayout>
#include <QTextCodec>
#include <QGraphicsDropShadowEffect>
#include <QStatusBar>
#include <QPalette>
#include <QLine>
#include <QDebug>
#include <QStackedWidget>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QCoreApplication>
#include <QEventLoop>
#include "QLineEdit"
#include <QScroller>
#include <QRegExp>
#include <QLabel>
#include <QEvent>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QToolButton>
#include <QMessageBox>
#include "softkey/softkeyboard.h"
#include "3rdparty/tinyxml2-master/tinyxml2.h"
#include <fstream>
#include <QQueue>
#include <QString>
#include "safe_thread_queue/safe_thread_queue.hpp"
#include <type_traits>
#include <QFontMetrics>
#include <QPainter>
#include <QTextEdit>
#include <QHostAddress>
#include "typeinfo"


using namespace tinyxml2;

struct PendantInterfaceInformationFrame
{
    QFrame* pageName;
    QFrame* codeFileName;
    QFrame* actionMode;
    QFrame* realTime;
};
extern PendantInterfaceInformationFrame pendantInterfaceInformationFrame;

struct PendantInterfaceInformation
{
    QLabel* pageName;
    QLabel* codeFileName;
    QLabel* actionMode;
    QLabel* realTime;
    QLabel *speedLabel;
};
extern PendantInterfaceInformation pendantInterfaceInformation;

struct PendantInterfaceData
{
    QString pageName;
    QString codeFileName;
    QString actionMode;
    QString realTime;
    QString speedMutableLabel;
};
extern PendantInterfaceData pendantInterfaceData;

QFrame* createSeparator();
QLabel* createLabel(const QString &text);
QWidget* createMenuWidget();
QFrame* createFrame(QWidget* widget,int w = 0,int h = 0,const QPoint point = {0,0});

void setPagesTopdisplayQlabel(QWidget* widget);
void setPagesTopdisplayData();
void setPagesTopStyle(QWidget* widget);
void setPagesTopFrame(QWidget* widget);


bool ispendantInterfaceDataChange();
void setLED(QLabel* label, int color, int size);
void setIoStatus(QLabel* ledIndex, int color, QLabel* ioName, const char *ioNameText);
void setSpeedValue(QLabel* speedMutableLabel);
void Sleep(int msec);
void setDefulatValue();
void initiateAlarmStruct();
void updateTimeLabel(QLabel* label);

void create_xml(const char* xmlPath);
void parse_xml(const char* xmlPath);
void traversal_node(XMLNode* node);
void traversal_element(XMLNode* node, int level);
void saveButtonState(const QString& buttonName, bool pressed);

extern QString  userLevel;
extern QString userPasswd[4];
extern QSettings *settings;

extern const char* sendPath;
extern const char* receivePath;
extern const char* docPath;
extern const char* programPath;

extern QString ipAddressString;
extern QString tcp_port;
extern QHostAddress ipAddress;

extern safe_thread_queue<QString> TCP_AlarmMsg_queue;
extern safe_thread_queue<QString> TCP_SendMsg_queue;
extern QString data_buffer_QS;

/*********************************** techn param list ***********************************/

typedef struct AlarmNumForType
{
    int AlarmNum_OperateError;
    int AlarmNum_Axis;
}AlarmNumForType_;

// 伺服数据,接收,name+attribute
typedef struct AxisParam
{
    double AxisPos;
    int EncodePos;
    bool IsZero;
    int AxisAcc;
    float AxisAccTime;
}AxisParam_;

// 输入出IO和IO反馈,发送接收,name+attribute
typedef struct IoParam
{
    bool X04;
    bool Y01;
    bool EmbraceOpen1;
}IoParam_;

// 输出控制,发送,name
typedef struct ButtonParam
{
    bool AddSpeed;
}ButtonParam_;

// 警报,接收,name
typedef struct AlarmParam
{
    QString* AlarmContent;
    bool* isAlarmTrigged;
    //bool* isAlarmTrigged_last;
}AlarmParam_;

// 伺服,发送接收,name+attribute
typedef struct ServoParam
{
    int SpeedRatio;
    int CorrectiveAxisAcc;
}ServoParam_;

// 系统,发送接收,name+attribute
typedef struct SysParam
{
}SysParam_;

typedef struct Techn_Param
{
    // 需要写入doc文件
    AxisParam_ AxisY;
    AxisParam_ AxisMX;
    AxisParam_ AxisMZ;
    AxisParam_ AxisSX;
    AxisParam_ AxisSZ;
    IoParam_ PendantIoParam;
    ServoParam_ PendantServoParam;

    // 不需要写入doc文件
    ButtonParam_ PendantButtonParam;
    AlarmParam_ OperateErrorAlarm;
    AlarmParam_ AxisAlarm;
}Techn_Param_, *Techn_Param_ptr;

extern Techn_Param_ Pendant_Techn_Param;
extern Techn_Param_ptr Pendant_Techn_Param_ptr;
extern AlarmNumForType_ PendantAlarmNumForType;

void setIoParam(const XMLElement *elementptr, const XMLAttribute *ele_attribute_ptr, Techn_Param_ptr tech_param);
void setAlarmParam(const XMLElement *elementptr, const XMLAttribute *ele_attribute_ptr, Techn_Param_ptr tech_param);
void RestoreTechnParam2Doc(Techn_Param_ptr Pendant_Techn_Param_ptr, const char* xmlPath);
void RestoreDoc2TechnParam(Techn_Param_ptr Pendant_Techn_Param_ptr, const char* xmlPath);
extern QIcon createCircleIcon(QColor color);
extern void setTableCellColor(QTableWidget* table, int row, int col, const QString & color_name);
extern void setTableCellText(QTableWidget* table, int row, int col, const QString & cell_text);
extern QString getStringFromTechnParam(double AxisPos, int EncodePos);

// 创建一个类型特征模板
template <typename T>
struct is_qstring : std::false_type {};
// 针对 QString 类型的部分特化
template <>
struct is_qstring<QString> : std::true_type {};


#endif // UTIL_H
